﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpShare.Storage;
using Dokan;
using SharpShare.Diagnostics;

namespace SharpShare.Vfs {
    public class VfsShareServer : ShareService, ILogProvider {
        private Dictionary<IStorageProvider, string> _mountPoints = new Dictionary<IStorageProvider, string>();

        public void AssignMountPoint(IStorageProvider share, string path) {
            _mountPoints[share] = path;
        }

        protected override void StartCore() {
            foreach (IStorageProvider share in this.Shares) {
                string letter = null;

                if (_mountPoints.ContainsKey(share)) {
                    letter = _mountPoints[share];
                }

                if (letter == null) {
                    continue;
                }

                new Action(() => {
                    //try {
                    //    System.IO.Directory.Delete(letter, true);
                    //} catch { }

                    try {
                        System.IO.Directory.CreateDirectory(letter);
                    } catch { }

                    Log.Add(this, EntryType.Information, "Attaching storage provider '{0}' to mount point '{1}'.", share, letter);

                    int result = DokanNet.DokanMain(new DokanOptions() {
                        MountPoint = letter,
                        VolumeLabel = share.Name
                    },
                    new StorageDokanOperations(share));

                    if (result != DokanNet.DOKAN_SUCCESS) {
                        Log.Add(this, EntryType.Error, "Mount point '{0}' detached with result {1}.", letter, result);
                    } else {
                        Log.Add(this, EntryType.Information, "Mount point '{0}' detached.", letter);
                    }
                }).BeginInvoke(null, null);
            }
        }

        protected override void StopCore() {
            foreach (IStorageProvider share in this.Shares) {
                string letter = null;

                if (_mountPoints.ContainsKey(share)) {
                    letter = _mountPoints[share];
                }

                if (letter == null) {
                    continue;
                }

                int result = DokanNet.DokanRemoveMountPoint(letter);

                if (result != 1) {
                    Log.Add(this, EntryType.Error, "Attempt to remove mount point '{0}' returned error {1}.", letter, result);
                } else {
                    Log.Add(this, EntryType.Information, "Mount point '{0}' removed.", letter);
                }
            }
        }

        #region ILogProvider Members

        string ILogProvider.Name {
            get {
                return "VFS";
            }
        }

        #endregion
    }
}
